﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Windows.Forms;
using System.Linq;
using LM.InterfacesFabricas.Basicos.Enumeradores;
using LM.InterfacesFabricas.DTOs;

namespace LM.Tela.Desktop
{
    public partial class frmItemTabelaPreco : Form
    {
        private const int ItemNaoSelecionadoCombo = -1;

        private frmTabelaPreco frmTabela;
        
        private DtoItemTabelaPreco _itemTabelaPreco;

        public List<DtoItemTabelaPreco> ListaDeItens { get; set; }

        public frmItemTabelaPreco(frmTabelaPreco frmTabelaPreco)
        {
            InitializeComponent();

            frmTabela = frmTabelaPreco;

            _itemTabelaPreco = new DtoItemTabelaPreco();
        }

        private void ckbSegunda_CheckedChanged(object sender, EventArgs e)
        {
            if (ckbSegunda.Checked)
            {
                ckbMatutinoSegunda.Checked = true;
                ckbVespertinoSegunda.Checked = true;
                ckbNoturnoSegunda.Checked = true;
            }
            else
            {
                ckbMatutinoSegunda.Checked = false;
                ckbVespertinoSegunda.Checked = false;
                ckbNoturnoSegunda.Checked = false;
            }
        }

        private void ckbDomingo_CheckedChanged(object sender, EventArgs e)
        {
            if (ckbDomingo.Checked)
            {
                ckbMatutinoDomingo.Checked = true;
                ckbVespertinoDomingo.Checked = true;
                ckbNoturnoDomingo.Checked = true;
            }
            else
            {
                ckbMatutinoDomingo.Checked = false;
                ckbVespertinoDomingo.Checked = false;
                ckbNoturnoDomingo.Checked = false;
            }
        }

        private void ckbTerca_CheckedChanged(object sender, EventArgs e)
        {
            if (ckbTerca.Checked)
            {
                ckbMatutinoTerca.Checked = true;
                ckbVespertinoTerca.Checked = true;
                ckbNoturnoTerca.Checked = true;
            }
            else
            {
                ckbMatutinoTerca.Checked = false;
                ckbVespertinoTerca.Checked = false;
                ckbNoturnoTerca.Checked = false;
            }
        }

        private void ckbQuarta_CheckedChanged(object sender, EventArgs e)
        {
            if (ckbQuarta.Checked)
            {
                ckbMatutinoQuarta.Checked = true;
                ckbVespertinoQuarta.Checked = true;
                ckbNoturnoQuarta.Checked = true;
            }
            else
            {
                ckbMatutinoQuarta.Checked = false;
                ckbVespertinoQuarta.Checked = false;
                ckbNoturnoQuarta.Checked = false;
            }
        }

        private void ckbQuinta_CheckedChanged(object sender, EventArgs e)
        {
            if (ckbQuinta.Checked)
            {
                ckbMatutinoQuinta.Checked = true;
                ckbVespertinoQuinta.Checked = true;
                ckbNoturnoQuinta.Checked = true;
            }
            else
            {
                ckbMatutinoQuinta.Checked = false;
                ckbVespertinoQuinta.Checked = false;
                ckbNoturnoQuinta.Checked = false;
            }
        }

        private void ckbSexta_CheckedChanged(object sender, EventArgs e)
        {
            if (ckbSexta.Checked)
            {
                ckbMatutinoSexta.Checked = true;
                ckbVespertinoSexta.Checked = true;
                ckbNoturnoSexta.Checked = true;
            }
            else
            {
                ckbMatutinoSexta.Checked = false;
                ckbVespertinoSexta.Checked = false;
                ckbNoturnoSexta.Checked = false;
            }
        }

        private void ckbSabado_CheckedChanged(object sender, EventArgs e)
        {
            if (ckbSabado.Checked)
            {
                ckbMatutinoSabado.Checked = true;
                ckbVespertinoSabado.Checked = true;
                ckbNoturnoSabado.Checked = true;
            }
            else
            {
                ckbMatutinoSabado.Checked = false;
                ckbVespertinoSabado.Checked = false;
                ckbNoturnoSabado.Checked = false;
            }
        }

        private void frmItemTabelaPreco_Load(object sender, EventArgs e)
        {
            CarragaTipoVagasCombo();
            CarragaTipoVeiculosCombo();

            PreparaParaNovaEdicao();
        }

        private void btnNovo_Click(object sender, EventArgs e)
        {
            PreparaParaNovaEdicao();
        }
        
        private void btnSalvar_Click(object sender, EventArgs e)
        {
            MontaItemDaTabelaApartirDoFormulario();

            if (!EmEdicao())
            {
                ListaDeItens.Add(_itemTabelaPreco);
            }
            else
            {
                ListaDeItens.Remove(ListaDeItens.FirstOrDefault(i => i.Codigo == _itemTabelaPreco.Codigo));
                ListaDeItens.Add(_itemTabelaPreco);
            }

            PreparaParaNovaEdicao();
        }

        private void btnExcluir_Click(object sender, EventArgs e)
        {
            MontaItemDaTabelaApartirDoFormulario();

            if (!ListaDeItens.Contains(_itemTabelaPreco))
            {
                ListaDeItens.Remove(_itemTabelaPreco);
            }

            PreparaParaNovaEdicao();
        }

        private void frmItemTabelaPreco_FormClosed(object sender, FormClosedEventArgs e)
        {
            if (frmTabela != null)
            {
                frmTabela.TabelaDePreco.ItensTabela = ListaDeItens;
                frmTabela.MostraTabelaPrecoNoFormulario();
            }
        }

        #region Métodos de Controle

        private void CarragaTipoVagasCombo()
        {
            cbxTipoVaga.DataSource = Enum.GetValues(typeof(EnumTipoDeVaga));
            cbxTipoVaga.SelectedIndex = ItemNaoSelecionadoCombo;
        }

        private void CarragaTipoVeiculosCombo()
        {
            cbxTipoVeiculo.DataSource = Enum.GetValues(typeof(EnumTipoDeVeiculo));
            cbxTipoVeiculo.SelectedIndex = ItemNaoSelecionadoCombo;
        }

        private void MontaItemTabelaPrecoNoFormulario(DtoItemTabelaPreco itemTabela)
        {
            if (itemTabela != null)
            {
                mskTxtCodigo.Text = itemTabela.Codigo.ToString(CultureInfo.InvariantCulture);
                cbxTipoVeiculo.SelectedItem = itemTabela.TipoVeiculo;
                cbxTipoVaga.SelectedItem = itemTabela.TipoVaga;
                mskTxtPeriodoInicial.Text = itemTabela.Periodo.ToString(@"hh\:mm");
                mskTxtCustoPeriodoInicial.Text = itemTabela.CustoPeriodo.ToString("0,0");
                
                if (itemTabela.PeriodoAdicional != null)
                {
                    mskTxtPeriodoAdicional.Text = itemTabela.PeriodoAdicional.ToString(@"hh\:mm");
                    mskCustoPerioroAdicional.Text = itemTabela.CustoPeriodo.ToString("0,0");
                }

                MontaDiasSemanaPeriodoDiaNoFormulario(itemTabela.DiasSemanaItemTabelaPrecos.ToList());

                mskTxtCodigo.Enabled = false;
            }
        }

        private void MontaDiasSemanaPeriodoDiaNoFormulario(IList<DtoDiaSemanaItemTabelaPreco> diasDaSemana)
        {
            if (diasDaSemana != null && diasDaSemana.Count > 0)
            {
                foreach (var dia in diasDaSemana)
                {
                    switch (dia.DiaDaSemana)
                    {
                        case EnumDiasSemana.Domingo :
                            ckbDomingo.Checked = true;
                            ckbMatutinoDomingo.Checked = dia.PeriodoDoDia.Any(p => p.PeriodoDia == EnumPeriodoDia.Matutino);
                            ckbVespertinoDomingo.Checked = dia.PeriodoDoDia.Any(p => p.PeriodoDia == EnumPeriodoDia.Vespertino);
                            ckbNoturnoDomingo.Checked = dia.PeriodoDoDia.Any(p => p.PeriodoDia == EnumPeriodoDia.Noturno);

                            break;

                        case EnumDiasSemana.Segunda :
                            ckbSegunda.Checked = true;
                            ckbMatutinoSegunda.Checked = dia.PeriodoDoDia.Any(p => p.PeriodoDia == EnumPeriodoDia.Matutino);
                            ckbVespertinoSegunda.Checked = dia.PeriodoDoDia.Any(p => p.PeriodoDia == EnumPeriodoDia.Vespertino);
                            ckbNoturnoSegunda.Checked = dia.PeriodoDoDia.Any(p => p.PeriodoDia == EnumPeriodoDia.Noturno);

                            break;

                        case EnumDiasSemana.Terca :
                            ckbTerca.Checked = true;
                            ckbMatutinoTerca.Checked = dia.PeriodoDoDia.Any(p => p.PeriodoDia == EnumPeriodoDia.Matutino);
                            ckbVespertinoTerca.Checked = dia.PeriodoDoDia.Any(p => p.PeriodoDia == EnumPeriodoDia.Vespertino);
                            ckbNoturnoTerca.Checked = dia.PeriodoDoDia.Any(p => p.PeriodoDia == EnumPeriodoDia.Noturno);

                            break;

                        case EnumDiasSemana.Quarta:
                            ckbQuarta.Checked = true;
                            ckbMatutinoQuarta.Checked = dia.PeriodoDoDia.Any(p => p.PeriodoDia == EnumPeriodoDia.Matutino);
                            ckbVespertinoQuarta.Checked = dia.PeriodoDoDia.Any(p => p.PeriodoDia == EnumPeriodoDia.Vespertino);
                            ckbNoturnoQuarta.Checked = dia.PeriodoDoDia.Any(p => p.PeriodoDia == EnumPeriodoDia.Noturno);

                            break;

                        case EnumDiasSemana.Quinta:
                            ckbQuinta.Checked = true;
                            ckbMatutinoQuinta.Checked = dia.PeriodoDoDia.Any(p => p.PeriodoDia == EnumPeriodoDia.Matutino);
                            ckbVespertinoQuinta.Checked = dia.PeriodoDoDia.Any(p => p.PeriodoDia == EnumPeriodoDia.Vespertino);
                            ckbNoturnoQuinta.Checked = dia.PeriodoDoDia.Any(p => p.PeriodoDia == EnumPeriodoDia.Noturno);

                            break;

                        case EnumDiasSemana.Sexta:
                            ckbSexta.Checked = true;
                            ckbMatutinoSexta.Checked = dia.PeriodoDoDia.Any(p => p.PeriodoDia == EnumPeriodoDia.Matutino);
                            ckbVespertinoSexta.Checked = dia.PeriodoDoDia.Any(p => p.PeriodoDia == EnumPeriodoDia.Vespertino);
                            ckbNoturnoSexta.Checked = dia.PeriodoDoDia.Any(p => p.PeriodoDia == EnumPeriodoDia.Noturno);

                            break;

                        case EnumDiasSemana.Sabado:
                            ckbSabado.Checked = true;
                            ckbMatutinoSabado.Checked = dia.PeriodoDoDia.Any(p => p.PeriodoDia == EnumPeriodoDia.Matutino);
                            ckbVespertinoSabado.Checked = dia.PeriodoDoDia.Any(p => p.PeriodoDia == EnumPeriodoDia.Vespertino);
                            ckbNoturnoSabado.Checked = dia.PeriodoDoDia.Any(p => p.PeriodoDia == EnumPeriodoDia.Noturno);

                            break;
                    }
                }
            }
        }

        private void MontaItemDaTabelaApartirDoFormulario()
        {
            int codigo;
            if (Int32.TryParse(mskTxtCodigo.Text.Trim(), NumberStyles.Integer, CultureInfo.InvariantCulture, out codigo))
            {
                _itemTabelaPreco.Codigo = codigo;
            }

            EnumTipoDeVeiculo tipoVeiculo;
            if (Enum.TryParse(cbxTipoVeiculo.SelectedItem == null ? string.Empty : cbxTipoVeiculo.SelectedItem.ToString(), true, out tipoVeiculo)
                && Enum.IsDefined(typeof (EnumTipoDeVeiculo), tipoVeiculo))
            {
                _itemTabelaPreco.TipoVeiculo = tipoVeiculo;
            }
            else
            {
                _itemTabelaPreco.TipoVeiculo = (EnumTipoDeVeiculo) 0;
            }

            EnumTipoDeVaga tipoVaga;
            if (Enum.TryParse(cbxTipoVaga.SelectedItem == null ? string.Empty : cbxTipoVaga.SelectedItem.ToString(), true, out tipoVaga)
                && Enum.IsDefined(typeof(EnumTipoDeVaga), tipoVaga))
            {
                _itemTabelaPreco.TipoVaga = tipoVaga;
            }
            else
            {
                _itemTabelaPreco.TipoVaga = (EnumTipoDeVaga) 0;
            }

            if (!string.IsNullOrWhiteSpace(mskTxtPeriodoInicial.Text.Trim().Replace(":", "")))
            {
                var periodoInicial = mskTxtPeriodoInicial.Text.Split(':');
                _itemTabelaPreco.Periodo = Int32.Parse(periodoInicial[0] + periodoInicial[1]);
            }
            else
            {
                _itemTabelaPreco.Periodo = 0;
            }

            if (!string.IsNullOrWhiteSpace(mskTxtCustoPeriodoInicial.Text.Trim()))
            {
                var custo = mskTxtCustoPeriodoInicial.Text.Trim().Replace(".", "");
                _itemTabelaPreco.CustoPeriodo = float.Parse(custo);
            }
            else
            {
                _itemTabelaPreco.CustoPeriodo = -1;
            }

            if (!string.IsNullOrWhiteSpace(mskTxtPeriodoAdicional.Text.Trim().Replace(":", "")))
            {
                var periodoFinal = mskTxtPeriodoAdicional.Text.Split(':');
                _itemTabelaPreco.PeriodoAdicional = Int32.Parse(periodoFinal[0] + periodoFinal[1]);
            }
            else
            {
                _itemTabelaPreco.PeriodoAdicional = 0;
            }

            if (!string.IsNullOrWhiteSpace(mskCustoPerioroAdicional.Text.Trim()))
            {
                var custo = mskCustoPerioroAdicional.Text.Trim().Replace(".", "");
                _itemTabelaPreco.CustoAdicional = float.Parse(custo);
            }
            else
            {
                _itemTabelaPreco.CustoAdicional = -1;
            }

            _itemTabelaPreco.DiasSemanaItemTabelaPrecos = ObtemDiasDaSemanaPeriodoDoFormulario();
        }

        private List<DtoDiaSemanaItemTabelaPreco> ObtemDiasDaSemanaPeriodoDoFormulario()
        {
            var dias = new List<DtoDiaSemanaItemTabelaPreco>();
            
            if (ckbDomingo.Checked)
            {
                var domingo = new DtoDiaSemanaItemTabelaPreco();
                domingo.DiaDaSemana = EnumDiasSemana.Domingo;
                domingo.PeriodoDoDia = new List<DtoPeriodoDoDia>();

                if (ckbMatutinoDomingo.Checked)
                {
                    domingo.PeriodoDoDia.Add(new DtoPeriodoDoDia(){PeriodoDia = EnumPeriodoDia.Matutino});
                }

                if (ckbVespertinoDomingo.Checked)
                {
                    domingo.PeriodoDoDia.Add(new DtoPeriodoDoDia() { PeriodoDia = EnumPeriodoDia.Vespertino });
                }

                if (ckbNoturnoDomingo.Checked)
                {
                    domingo.PeriodoDoDia.Add(new DtoPeriodoDoDia() { PeriodoDia = EnumPeriodoDia.Noturno });
                }

                dias.Add(domingo);
            }

            if (ckbSegunda.Checked)
            {
                var segunda = new DtoDiaSemanaItemTabelaPreco();
                segunda.DiaDaSemana = EnumDiasSemana.Segunda;
                segunda.PeriodoDoDia = new List<DtoPeriodoDoDia>();

                if (ckbMatutinoSegunda.Checked)
                {
                    segunda.PeriodoDoDia.Add(new DtoPeriodoDoDia() { PeriodoDia = EnumPeriodoDia.Matutino });
                }

                if (ckbVespertinoSegunda.Checked)
                {
                    segunda.PeriodoDoDia.Add(new DtoPeriodoDoDia() { PeriodoDia = EnumPeriodoDia.Vespertino });
                }

                if (ckbNoturnoSegunda.Checked)
                {
                    segunda.PeriodoDoDia.Add(new DtoPeriodoDoDia() { PeriodoDia = EnumPeriodoDia.Noturno });
                }

                dias.Add(segunda);
            }

            if (ckbTerca.Checked)
            {
                var terca = new DtoDiaSemanaItemTabelaPreco();
                terca.DiaDaSemana = EnumDiasSemana.Terca;
                terca.PeriodoDoDia = new List<DtoPeriodoDoDia>();

                if (ckbMatutinoTerca.Checked)
                {
                    terca.PeriodoDoDia.Add(new DtoPeriodoDoDia() { PeriodoDia = EnumPeriodoDia.Matutino });
                }

                if (ckbVespertinoTerca.Checked)
                {
                    terca.PeriodoDoDia.Add(new DtoPeriodoDoDia() { PeriodoDia = EnumPeriodoDia.Vespertino });
                }

                if (ckbNoturnoTerca.Checked)
                {
                    terca.PeriodoDoDia.Add(new DtoPeriodoDoDia() { PeriodoDia = EnumPeriodoDia.Noturno });
                }

                dias.Add(terca);
            }

            if (ckbQuarta.Checked)
            {
                var quarta = new DtoDiaSemanaItemTabelaPreco();
                quarta.DiaDaSemana = EnumDiasSemana.Quarta;
                quarta.PeriodoDoDia = new List<DtoPeriodoDoDia>();

                if (ckbMatutinoQuarta.Checked)
                {
                    quarta.PeriodoDoDia.Add(new DtoPeriodoDoDia() { PeriodoDia = EnumPeriodoDia.Matutino });
                }

                if (ckbVespertinoQuarta.Checked)
                {
                    quarta.PeriodoDoDia.Add(new DtoPeriodoDoDia() { PeriodoDia = EnumPeriodoDia.Vespertino });
                }

                if (ckbNoturnoQuarta.Checked)
                {
                    quarta.PeriodoDoDia.Add(new DtoPeriodoDoDia() { PeriodoDia = EnumPeriodoDia.Noturno });
                }

                dias.Add(quarta);
            }

            if (ckbQuinta.Checked)
            {
                var quinta = new DtoDiaSemanaItemTabelaPreco();
                quinta.DiaDaSemana = EnumDiasSemana.Quinta;
                quinta.PeriodoDoDia = new List<DtoPeriodoDoDia>();

                if (ckbMatutinoQuinta.Checked)
                {
                    quinta.PeriodoDoDia.Add(new DtoPeriodoDoDia() { PeriodoDia = EnumPeriodoDia.Matutino });
                }

                if (ckbVespertinoQuinta.Checked)
                {
                    quinta.PeriodoDoDia.Add(new DtoPeriodoDoDia() { PeriodoDia = EnumPeriodoDia.Vespertino });
                }

                if (ckbNoturnoQuinta.Checked)
                {
                    quinta.PeriodoDoDia.Add(new DtoPeriodoDoDia() { PeriodoDia = EnumPeriodoDia.Noturno });
                }

                dias.Add(quinta);
            }

            if (ckbSexta.Checked)
            {
                var sexta = new DtoDiaSemanaItemTabelaPreco();
                sexta.DiaDaSemana = EnumDiasSemana.Sexta;
                sexta.PeriodoDoDia = new List<DtoPeriodoDoDia>();

                if (ckbMatutinoSexta.Checked)
                {
                    sexta.PeriodoDoDia.Add(new DtoPeriodoDoDia() { PeriodoDia = EnumPeriodoDia.Matutino });
                }

                if (ckbVespertinoSexta.Checked)
                {
                    sexta.PeriodoDoDia.Add(new DtoPeriodoDoDia() { PeriodoDia = EnumPeriodoDia.Vespertino });
                }

                if (ckbNoturnoSexta.Checked)
                {
                    sexta.PeriodoDoDia.Add(new DtoPeriodoDoDia() { PeriodoDia = EnumPeriodoDia.Noturno });
                }

                dias.Add(sexta);
            }

            if (ckbSabado.Checked)
            {
                var sabado = new DtoDiaSemanaItemTabelaPreco();
                sabado.DiaDaSemana = EnumDiasSemana.Sabado;
                sabado.PeriodoDoDia = new List<DtoPeriodoDoDia>();

                if (ckbMatutinoSabado.Checked)
                {
                    sabado.PeriodoDoDia.Add(new DtoPeriodoDoDia() { PeriodoDia = EnumPeriodoDia.Matutino });
                }

                if (ckbVespertinoSabado.Checked)
                {
                    sabado.PeriodoDoDia.Add(new DtoPeriodoDoDia() { PeriodoDia = EnumPeriodoDia.Vespertino });
                }

                if (ckbNoturnoSabado.Checked)
                {
                    sabado.PeriodoDoDia.Add(new DtoPeriodoDoDia() { PeriodoDia = EnumPeriodoDia.Noturno });
                }

                dias.Add(sabado);
            }
            
            return dias;
        }

        private void PreparaParaNovaEdicao()
        {
            _itemTabelaPreco = new DtoItemTabelaPreco();

            mskTxtCodigo.Text = string.Empty;
            mskTxtCodigo.Enabled = true;

            cbxTipoVeiculo.SelectedIndex = ItemNaoSelecionadoCombo;
            cbxTipoVaga.SelectedIndex = ItemNaoSelecionadoCombo;

            mskTxtPeriodoInicial.Text = string.Empty;
            mskTxtCustoPeriodoInicial.Text = string.Empty;
            mskTxtPeriodoAdicional.Text = string.Empty;
            mskCustoPerioroAdicional.Text = string.Empty;

            ckbDomingo.Checked = false;
            ckbSegunda.Checked = false;
            ckbTerca.Checked = false;
            ckbQuarta.Checked = false;
            ckbQuinta.Checked = false;
            ckbSexta.Checked = false;
            ckbSabado.Checked = false;

            BindCbxItens();

            cbxItens.SelectedIndex = ItemNaoSelecionadoCombo;
        }

        private bool EmEdicao()
        {
            return !string.IsNullOrWhiteSpace(mskTxtCodigo.Text) && mskTxtCodigo.Enabled == false;
        }

        private void BindCbxItens()
        {
            cbxItens.DataSource = null;
            cbxItens.DataSource = ListaDeItens;
        }
        
        #endregion

        private void cbxItens_SelectedIndexChanged(object sender, EventArgs e)
        {
            var combo = (ComboBox) sender;
            
            if (combo.SelectedIndex >= 0)
            {
                _itemTabelaPreco = (DtoItemTabelaPreco) combo.SelectedItem;

                MontaItemTabelaPrecoNoFormulario(_itemTabelaPreco);
            }
        }
    }
}
